/* -*- Mode: C; c-basic-offset: 4 -*-
 * pygtk- Python bindings for the GTK toolkit.
 * Copyright (C) 1998-2006  James Henstridge
 *
 *   gtktextview.override: overrides for the gtk.TextView object.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 * USA
 */
%%
ignore-glob
  gtk_text_view_new

%%
override gtk_text_view_get_visible_rect noargs
static PyObject *
_wrap_gtk_text_view_get_visible_rect(PyGObject *self)
{
    GdkRectangle visible_rect;

    gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(self->obj), &visible_rect);
    return pyg_boxed_new(GDK_TYPE_RECTANGLE, &visible_rect, TRUE, TRUE);
}
%%
override gtk_text_view_buffer_to_window_coords kwargs
static PyObject *
_wrap_gtk_text_view_buffer_to_window_coords(PyGObject *self, PyObject *args,
                                            PyObject *kwargs)
{
    static char *kwlist[] = { "win", "buffer_x", "buffer_y", NULL };
    GtkTextWindowType win;
    gint buffer_x, buffer_y, window_x = 0, window_y = 0;
    PyObject *py_win;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "Oii:GtkTextView.buffer_to_window_coords",
                                     kwlist, &py_win, &buffer_x, &buffer_y))
        return NULL;
    if (pyg_enum_get_value(GTK_TYPE_TEXT_WINDOW_TYPE, py_win, (gint *)&win))
        return NULL;
    gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(self->obj), win,
                                          buffer_x, buffer_y,
                                          &window_x, &window_y);
    return Py_BuildValue("(ii)", window_x, window_y);
}
%%
override gtk_text_view_window_to_buffer_coords kwargs
static PyObject *
_wrap_gtk_text_view_window_to_buffer_coords(PyGObject *self, PyObject *args,
                                            PyObject *kwargs)
{
    static char *kwlist[] = { "win", "window_x", "window_y", NULL };
    GtkTextWindowType win;
    gint window_x, window_y, buffer_x = 0, buffer_y = 0;
    PyObject *py_win;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "Oii:GtkTextView.window_to_buffer_coords",
                                     kwlist, &py_win, &window_x, &window_y))
        return NULL;
    if (pyg_enum_get_value(GTK_TYPE_TEXT_WINDOW_TYPE, py_win, (gint *)&win))
        return NULL;
    gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(self->obj), win,
                                          window_x, window_y,
                                          &buffer_x, &buffer_y);
    return Py_BuildValue("(ii)", buffer_x, buffer_y);
}
%%
override gtk_text_view_get_iter_location kwargs
static PyObject *
_wrap_gtk_text_view_get_iter_location(PyGObject *self, PyObject *args,
                                      PyObject *kwargs)
{
    static char *kwlist[] = { "iter", NULL };
    PyObject *py_iter;
    GdkRectangle location;
    GtkTextIter *iter = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "O:GtkTextView.get_iter_location",
                                     kwlist, &py_iter))
        return NULL;
    if (pyg_boxed_check(py_iter, GTK_TYPE_TEXT_ITER))
        iter = pyg_boxed_get(py_iter, GtkTextIter);
    else {
        PyErr_SetString(PyExc_TypeError, "iter should be a GtkTextIter");
        return NULL;
    }
    gtk_text_view_get_iter_location(GTK_TEXT_VIEW(self->obj), iter, &location);
    return pyg_boxed_new(GDK_TYPE_RECTANGLE, &location, TRUE, TRUE);
}
%%
override gtk_text_view_get_line_at_y kwargs
static PyObject *
_wrap_gtk_text_view_get_line_at_y(PyGObject *self, PyObject *args,
                                  PyObject *kwargs)
{
    static char *kwlist[] = { "y", NULL };
    GtkTextIter iter;
    gint y, line_top;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "i:GtkTextView.get_line_at_y",
                                     kwlist, &y))
        return NULL;
    gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(self->obj),
                                &iter, y, &line_top);
    return Py_BuildValue("(Ni)",
                         pyg_boxed_new(GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE),
                         line_top);
}
%%
override gtk_text_view_get_line_yrange kwargs
static PyObject *
_wrap_gtk_text_view_get_line_yrange(PyGObject *self, PyObject *args,
                                  PyObject *kwargs)
{
    static char *kwlist[] = { "iter", NULL };
    GtkTextIter *iter = NULL;
    gint y = -1, height = -1;
    PyObject *py_iter;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "O:GtkTextView.get_line_yrange",
                                     kwlist, &py_iter))
        return NULL;
    if (pyg_boxed_check(py_iter, GTK_TYPE_TEXT_ITER))
        iter = pyg_boxed_get(py_iter, GtkTextIter);
    else {
        PyErr_SetString(PyExc_TypeError, "iter should be a GtkTextIter");
        return NULL;
    }
    gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(self->obj),
                                  iter, &y, &height);
    return Py_BuildValue("(ii)", y, height);
}
%%
override gtk_text_view_get_iter_at_location kwargs
static PyObject *
_wrap_gtk_text_view_get_iter_at_location(PyGObject *self, PyObject *args,
                                         PyObject *kwargs)
{
    static char *kwlist[] = { "x", "y", NULL };
    GtkTextIter iter;
    gint x, y;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "ii:GtkTextView.get_iter_at_location",
                                     kwlist, &x, &y))
        return NULL;
    gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(self->obj),
                                       &iter, x, y);
    return pyg_boxed_new(GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE);
}
%%
override gtk_text_view_set_border_window_size kwargs
static PyObject *
_wrap_gtk_text_view_set_border_window_size(PyGObject *self, PyObject *args,
					   PyObject *kwargs)
{
    static char *kwlist[] = { "type", "size", NULL };
    PyObject *py_type = NULL;
    int size;
    GtkTextWindowType type;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
				     "Oi:GtkTextView.set_border_window_size",
				     kwlist, &py_type, &size))
        return NULL;

    if (size < 0) {
        PyErr_SetString(PyExc_ValueError, "size must be >= 0");
	return NULL;
    }

    if (pyg_enum_get_value(GTK_TYPE_TEXT_WINDOW_TYPE, py_type, (gint *)&type))
        return NULL;

    switch (type)
    {
    case GTK_TEXT_WINDOW_LEFT:
    case GTK_TEXT_WINDOW_RIGHT:
    case GTK_TEXT_WINDOW_TOP:
    case GTK_TEXT_WINDOW_BOTTOM:
	gtk_text_view_set_border_window_size(GTK_TEXT_VIEW(self->obj), type,
					     size);
	break;
    default:
        PyErr_SetString(PyExc_ValueError, "type must be one of: "
			"gtk.TEXT_WINDOW_LEFT, gtk.TEXT_WINDOW_RIGHT, "
			"gtk.TEXT_WINDOW_TOP or gtk.TEXT_WINDOW_BOTTOM");
	return NULL;
    }
	
    Py_INCREF(Py_None);
    return Py_None;
}
%%
ignore gtk_text_iter_free
%%
override gtk_text_iter_copy noargs
static PyObject *
_wrap_gtk_text_iter_copy(PyGBoxed *self)
{
    return pyg_boxed_new(GTK_TYPE_TEXT_ITER, pyg_boxed_get(self, GtkTextIter),
                         TRUE, TRUE);
}
%%
define GtkTextIter.assign kwargs
static PyObject *
_wrap_gtk_text_iter_assign(PyGBoxed *self, PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = { "other", NULL };
    PyGBoxed *other;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:gtk.TextIter.assign",
                                     kwlist, &other))
        return NULL;
    if (!pyg_boxed_check(other, GTK_TYPE_TEXT_ITER)) {
        PyErr_SetString(PyExc_TypeError, "other must be a GtkTextIter");
        return NULL;
    }

    *pyg_boxed_get(self, GtkTextIter) = *pyg_boxed_get(other, GtkTextIter);

    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_text_iter_get_slice kwargs
static PyObject *
_wrap_gtk_text_iter_get_slice(PyGBoxed *self, PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = { "end", NULL };
    PyGBoxed *end;
    gchar *text;
    PyObject *pytext;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GtkTextIter.get_slice",
                                     kwlist, &end))
        return NULL;
    if (!pyg_boxed_check(end, GTK_TYPE_TEXT_ITER)) {
        PyErr_SetString(PyExc_TypeError, "end must be a GtkTextIter");
        return NULL;
    }
    text = gtk_text_iter_get_slice(pyg_boxed_get(self, GtkTextIter),
                                   pyg_boxed_get(end, GtkTextIter));
    pytext = PyUnicode_DecodeUTF8(text, strlen(text), "strict");
    g_free(text);
    return pytext;
}
%%
override gtk_text_iter_get_text kwargs
static PyObject *
_wrap_gtk_text_iter_get_text(PyGBoxed *self, PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = { "end", NULL };
    PyGBoxed *end;
    gchar *text;
    PyObject *pytext;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GtkTextIter.get_text",
                                     kwlist, &end))
        return NULL;
    if (!pyg_boxed_check(end, GTK_TYPE_TEXT_ITER)) {
        PyErr_SetString(PyExc_TypeError, "end must be a GtkTextIter");
        return NULL;
    }
    text = gtk_text_iter_get_text(pyg_boxed_get(self, GtkTextIter),
                                   pyg_boxed_get(end, GtkTextIter));
    pytext = PyUnicode_DecodeUTF8(text, strlen(text), "strict");
    g_free(text);
    return pytext;
}
%%
override gtk_text_iter_get_visible_slice kwargs
static PyObject *
_wrap_gtk_text_iter_get_visible_slice(PyGBoxed *self, PyObject *args,
                                      PyObject *kwargs)
{
    static char *kwlist[] = { "end", NULL };
    PyGBoxed *end;
    gchar *text;
    PyObject *pytext;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "O:GtkTextIter.get_visible_slice", kwlist,
                                     &end))
        return NULL;
    if (!pyg_boxed_check(end, GTK_TYPE_TEXT_ITER)) {
        PyErr_SetString(PyExc_TypeError, "end must be a GtkTextIter");
        return NULL;
    }
    text = gtk_text_iter_get_visible_slice(pyg_boxed_get(self, GtkTextIter),
                                           pyg_boxed_get(end, GtkTextIter));
    pytext = PyUnicode_DecodeUTF8(text, strlen(text), "strict");
    g_free(text);
    return pytext;
}
%%
override gtk_text_iter_get_visible_text kwargs
static PyObject *
_wrap_gtk_text_iter_get_visible_text(PyGBoxed *self, PyObject *args,
                                     PyObject *kwargs)
{
    static char *kwlist[] = { "end", NULL };
    PyGBoxed *end;
    gchar *text;
    PyObject *pytext;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "O:GtkTextIter.get_visible_text", kwlist,
                                     &end))
        return NULL;
    if (!pyg_boxed_check(end, GTK_TYPE_TEXT_ITER)) {
        PyErr_SetString(PyExc_TypeError, "end must be a GtkTextIter");
        return NULL;
    }
    text = gtk_text_iter_get_visible_text(pyg_boxed_get(self, GtkTextIter),
                                          pyg_boxed_get(end, GtkTextIter));
    pytext = PyUnicode_DecodeUTF8(text, strlen(text), "strict");
    g_free(text);
    return pytext;
}
%%
override gtk_text_iter_get_marks noargs
static PyObject *
_wrap_gtk_text_iter_get_marks(PyGBoxed *self)
{
    GSList *ret, *tmp;
    PyObject *pyret;

    ret = gtk_text_iter_get_marks(pyg_boxed_get(self, GtkTextIter));
    pyret = PyList_New(0);
    for (tmp = ret; tmp != NULL; tmp = tmp->next) {
        PyObject *mark = pygobject_new((GObject *)tmp->data);
        PyList_Append(pyret, mark);
        Py_DECREF(mark);
    }
    g_slist_free(ret);
    return pyret;
}
%%
override gtk_text_iter_get_toggled_tags kwargs
static PyObject *
_wrap_gtk_text_iter_get_toggled_tags(PyGBoxed *self, PyObject *args,
                                     PyObject *kwargs)
{
    static char *kwlist[] = { "toggled_on", NULL };
    GSList *ret, *tmp;
    int toggled_on;
    PyObject *pyret;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "i:GtkTextIter.get_toggled_tags", kwlist,
                                     &toggled_on))
        return NULL;
    ret = gtk_text_iter_get_toggled_tags(pyg_boxed_get(self, GtkTextIter),
                                         toggled_on);
    pyret = PyList_New(0);
    for (tmp = ret; tmp != NULL; tmp = tmp->next) {
        PyObject *tag = pygobject_new((GObject *)tmp->data);
        PyList_Append(pyret, tag);
        Py_DECREF(tag);
    }
    g_slist_free(ret);
    return pyret;
}
%%
override gtk_text_iter_get_tags noargs
static PyObject *
_wrap_gtk_text_iter_get_tags(PyGBoxed *self)
{
    GSList *ret, *tmp;
    PyObject *pyret;

    ret = gtk_text_iter_get_tags(pyg_boxed_get(self, GtkTextIter));
    pyret = PyList_New(0);
    for (tmp = ret; tmp != NULL; tmp = tmp->next) {
        PyObject *tag = pygobject_new((GObject *)tmp->data);
        PyList_Append(pyret, tag);
        Py_DECREF(tag);
    }
    g_slist_free(ret);
    return pyret;
}
%%
override gtk_text_iter_forward_search kwargs
static PyObject *
_wrap_gtk_text_iter_forward_search(PyGBoxed *self, PyObject *args,
                                   PyObject *kwargs)
{
    static char *kwlist[] = { "str", "flags", "limit", NULL };
    gchar *str;
    PyObject *py_flags, *py_limit = Py_None;
    GtkTextIter match_start, match_end, *limit = NULL;
    GtkTextSearchFlags flags;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "sO|O:GtkTextIter.forward_search",
                                     kwlist, &str, &py_flags, &py_limit))
        return NULL;
    if (pyg_boxed_check(py_limit, GTK_TYPE_TEXT_ITER))
        limit = pyg_boxed_get(py_limit, GtkTextIter);
    else if (py_limit != Py_None) {
        PyErr_SetString(PyExc_TypeError,"limit must be a GtkTextIter or None");
        return NULL;
    }
    if (pyg_flags_get_value(GTK_TYPE_TEXT_SEARCH_FLAGS, py_flags,
                            (gint *)&flags))
        return NULL;
    if (gtk_text_iter_forward_search(pyg_boxed_get(self, GtkTextIter), str,
                                     flags, &match_start, &match_end, limit))
        return Py_BuildValue("(NN)",
                             pyg_boxed_new(GTK_TYPE_TEXT_ITER, &match_start,
                                           TRUE, TRUE),
                             pyg_boxed_new(GTK_TYPE_TEXT_ITER, &match_end,
                                           TRUE, TRUE));
    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_text_iter_backward_search kwargs
static PyObject *
_wrap_gtk_text_iter_backward_search(PyGBoxed *self, PyObject *args,
                                    PyObject *kwargs)
{
    static char *kwlist[] = { "str", "flags", "limit", NULL };
    gchar *str;
    PyObject *py_flags, *py_limit = Py_None;
    GtkTextIter match_start, match_end, *limit = NULL;
    GtkTextSearchFlags flags;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "sO|O:GtkTextIter.backward_search",
                                     kwlist, &str, &py_flags, &py_limit))
        return NULL;
    if (pyg_boxed_check(py_limit, GTK_TYPE_TEXT_ITER))
        limit = pyg_boxed_get(py_limit, GtkTextIter);
    else if (py_limit != Py_None) {
        PyErr_SetString(PyExc_TypeError,"limit must be a GtkTextIter or None");
        return NULL;
    }
    if (pyg_flags_get_value(GTK_TYPE_TEXT_SEARCH_FLAGS, py_flags,
                            (gint *)&flags))
        return NULL;
    if (gtk_text_iter_backward_search(pyg_boxed_get(self, GtkTextIter), str,
                                      flags, &match_start, &match_end, limit))
        return Py_BuildValue("(NN)",
                             pyg_boxed_new(GTK_TYPE_TEXT_ITER, &match_start,
                                           TRUE, TRUE),
                             pyg_boxed_new(GTK_TYPE_TEXT_ITER, &match_end,
                                           TRUE, TRUE));
    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_text_buffer_insert_with_tags
static PyObject *
_wrap_gtk_text_buffer_insert_with_tags(PyGObject *self, PyObject *args)
{
    PyObject *first, *py_iter;
    gint len, i, start_offset;
    Py_ssize_t text_len;
    gchar *text;
    GtkTextIter *iter, start;

    len = PyTuple_Size(args);
    if (len < 2) {
        PyErr_SetString(PyExc_TypeError,
            "GtkTextBuffer.insert_with_tags requires at least 2 arguments");
        return NULL;
    }
    first = PySequence_GetSlice(args, 0, 2);
    if (!PyArg_ParseTuple(first, "Os#:GtkTextBuffer.insert_with_tags",
                          &py_iter, &text, &text_len)) {
        Py_DECREF(first);
        return NULL;
    }
    Py_DECREF(first);
    if (!pyg_boxed_check(py_iter, GTK_TYPE_TEXT_ITER)) {
        PyErr_SetString(PyExc_TypeError, "iter must be a GtkTextIter");
        return NULL;
    }
    iter = pyg_boxed_get(py_iter, GtkTextIter);

    /* check types */
    for (i = 2; i < len; i++) {
        PyObject *item = PyTuple_GetItem(args, i);

        if (!pygobject_check(item, &PyGtkTextTag_Type)) {
            PyErr_SetString(PyExc_TypeError,
                            "additional argument must be a GtkTextTag");
            return NULL;
        }
    }

    start_offset = gtk_text_iter_get_offset(iter);
    gtk_text_buffer_insert(GTK_TEXT_BUFFER(self->obj), iter, text, text_len);
    gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(self->obj),
                                       &start, start_offset);

    for (i = 2; i < len; i++) {
        PyObject *item = PyTuple_GetItem(args, i);
        GtkTextTag *tag = GTK_TEXT_TAG(pygobject_get(item));

        gtk_text_buffer_apply_tag(GTK_TEXT_BUFFER(self->obj), tag,&start,iter);
    }

    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_text_buffer_insert_with_tags_by_name
static PyObject *
_wrap_gtk_text_buffer_insert_with_tags_by_name(PyGObject *self, PyObject *args)
{
    PyObject *first, *py_iter;
    gint len, i, start_offset;
    Py_ssize_t text_len;
    gchar *text;
    GtkTextIter *iter, start;

    len = PyTuple_Size(args);
    if (len < 2) {
        PyErr_SetString(PyExc_TypeError,
                        "GtkTextBuffer.insert_with_tags_by_name "
                        "requires at least 2 arguments");
        return NULL;
    }
    first = PySequence_GetSlice(args, 0, 2);
    if (!PyArg_ParseTuple(first, "Os#:GtkTextBuffer.insert_with_tags_by_name",
                          &py_iter, &text, &text_len)) {
        Py_DECREF(first);
        return NULL;
    }
    Py_DECREF(first);
    if (!pyg_boxed_check(py_iter, GTK_TYPE_TEXT_ITER)) {
        PyErr_SetString(PyExc_TypeError, "iter must be a GtkTextIter");
        return NULL;
    }
    iter = pyg_boxed_get(py_iter, GtkTextIter);

    /* check types */
    for (i = 2; i < len; i++) {
        PyObject *item = PyTuple_GetItem(args, i);

        if (!PyString_Check(item)) {
            PyErr_SetString(PyExc_TypeError,
                            "additional argument must be a string");
            return NULL;
        }
    }

    start_offset = gtk_text_iter_get_offset(iter);
    gtk_text_buffer_insert(GTK_TEXT_BUFFER(self->obj), iter, text, text_len);
    gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(self->obj),
                                       &start, start_offset);

    for (i = 2; i < len; i++) {
        PyObject *item = PyTuple_GetItem(args, i);
        const gchar *tagname = PyString_AsString(item);

        gtk_text_buffer_apply_tag_by_name(GTK_TEXT_BUFFER(self->obj),
                                          tagname, &start, iter);
    }

    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_text_buffer_create_tag kwargs
static PyObject *
_wrap_gtk_text_buffer_create_tag(PyGObject *self, PyObject *args, PyObject *kwargs)
{
    gchar *tag_name = NULL;
    GtkTextTag *tag;
    GtkTextTagTable *table;

    if (!PyArg_ParseTuple(args, "|z:GtkTextBuffer.create_tag",
                          &tag_name)) {
        return NULL;
    }

    table = GTK_TEXT_TAG_TABLE(GTK_TEXT_BUFFER(self->obj)->tag_table);
    if (tag_name && table && g_hash_table_lookup(table->hash, tag_name)) {
        gchar buf[512];
        g_snprintf(buf, sizeof(buf),
                   "A tag named '%s' is already in the tag table",
                   tag_name);

        PyErr_SetString(PyExc_TypeError, buf);
        return NULL;
    }

    tag = gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(self->obj),
                                     tag_name, NULL);

    /* set tag properties if any */
    if (kwargs) {
        Py_ssize_t i = 0;
        PyObject *prop, *val;

        while (PyDict_Next(kwargs, &i, &prop, &val)) {
            GParamSpec *pspec;
            GValue value = { 0, };
            gchar *prop_str = PyString_AsString(prop);

            pspec = g_object_class_find_property (G_OBJECT_GET_CLASS(tag),
                                                  prop_str);
            if (!pspec) {
                PyErr_Format(PyExc_TypeError,
                             "unsupported tag property `%s'",
                             prop_str);
                /* XXX: Free tag? */
                return NULL;
            }

            g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
            if (pyg_value_from_pyobject(&value, val) < 0) {
                PyErr_Format(PyExc_TypeError,
                     "could not convert tag property '%s' to correct type",
                             prop_str);
                /* XXX: Free tag? */
                return NULL;
            }
            g_object_set_property((GObject *)tag, prop_str, &value);
            g_value_unset(&value);
       }
    }
    return pygobject_new((GObject *)tag);
}
%%
override gtk_text_buffer_get_iter_at_line_offset kwargs
static PyObject *
_wrap_gtk_text_buffer_get_iter_at_line_offset(PyGObject *self, PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = { "line_number", "char_offset", NULL };
    GtkTextIter iter;
    int line_number, char_offset;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:GtkTextBuffer.get_iter_at_line_offset", kwlist, &line_number, &char_offset))
        return NULL;

    gtk_text_buffer_get_iter_at_line_offset(GTK_TEXT_BUFFER(self->obj), &iter,
                                            line_number, char_offset);
    return pyg_boxed_new(GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE);
}
%%
override gtk_text_buffer_get_iter_at_line_index kwargs
static PyObject *
_wrap_gtk_text_buffer_get_iter_at_line_index(PyGObject *self, PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = { "line_number", "byte_offset", NULL };
    GtkTextIter iter;
    int line_number, byte_offset;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:GtkTextBuffer.get_iter_at_line_index", kwlist, &line_number, &byte_offset))
        return NULL;

    gtk_text_buffer_get_iter_at_line_index(GTK_TEXT_BUFFER(self->obj), &iter,
                                           line_number, byte_offset);
    return pyg_boxed_new(GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE);
}
%%
override gtk_text_buffer_get_iter_at_offset kwargs
static PyObject *
_wrap_gtk_text_buffer_get_iter_at_offset(PyGObject *self, PyObject *args, PyObject *kwargs)
{
    int char_offset;
    static char *kwlist[] = { "char_offset", NULL };
    GtkTextIter iter;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:GtkTextBuffer.get_iter_at_offset", kwlist, &char_offset))
        return NULL;

    gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(self->obj),
                                       &iter, char_offset);
    return pyg_boxed_new(GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE);
}
%%
override gtk_text_buffer_get_iter_at_line kwargs
static PyObject *
_wrap_gtk_text_buffer_get_iter_at_line(PyGObject *self, PyObject *args, PyObject *kwargs)
{
    int line_number;
    static char *kwlist[] = { "line_number", NULL };
    GtkTextIter iter;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:GtkTextBuffer.get_iter_at_line", kwlist, &line_number))
        return NULL;

    gtk_text_buffer_get_iter_at_line(GTK_TEXT_BUFFER(self->obj),
                                     &iter, line_number);
    return pyg_boxed_new(GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE);
}
%%
override gtk_text_buffer_get_start_iter noargs
static PyObject *
_wrap_gtk_text_buffer_get_start_iter(PyGObject *self)
{
    GtkTextIter iter;

    gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(self->obj), &iter);
    return pyg_boxed_new(GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE);
}
%%
override gtk_text_buffer_get_end_iter noargs
static PyObject *
_wrap_gtk_text_buffer_get_end_iter(PyGObject *self)
{
    GtkTextIter iter;

    gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(self->obj), &iter);
    return pyg_boxed_new(GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE);
}
%%
override gtk_text_buffer_get_bounds noargs
static PyObject *
_wrap_gtk_text_buffer_get_bounds(PyGObject *self)
{
    GtkTextIter start, end;

    gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(self->obj), &start, &end);
    return Py_BuildValue("(NN)",
                         pyg_boxed_new(GTK_TYPE_TEXT_ITER, &start, TRUE, TRUE),
                         pyg_boxed_new(GTK_TYPE_TEXT_ITER, &end, TRUE, TRUE));
}
%%
override gtk_text_buffer_get_iter_at_mark kwargs
static PyObject *
_wrap_gtk_text_buffer_get_iter_at_mark(PyGObject *self, PyObject *args, PyObject *kwargs)
{
    PyGObject *mark;
    static char *kwlist[] = { "mark", NULL };
    GtkTextIter iter;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GtkTextBuffer.get_iter_at_mark", kwlist, &mark))
        return NULL;
    if (!pygobject_check(mark, &PyGtkTextMark_Type)) {
        PyErr_SetString(PyExc_TypeError, "mark should be a GtkTextMark");
        return NULL;
    }

    gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(self->obj), &iter,
                                     GTK_TEXT_MARK(mark->obj));
    return pyg_boxed_new(GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE);
}
%%
override gtk_text_buffer_set_text kwargs
static PyObject *
_wrap_gtk_text_buffer_set_text(PyGObject *self, PyObject *args, PyObject *kwargs)
{
    char *text;
    static char *kwlist[] = { "text", "len", NULL };
    Py_ssize_t len;
    int oldlen = -1;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "s#|i:GtkTextBuffer.set_text", kwlist,
                                     &text, &len, &oldlen)) {
        return NULL;
    }

    if (oldlen > 0) {
	if (oldlen > len) {
	    PyErr_SetString(PyExc_ValueError, "len greater than text length");
	    return NULL;
	}
	len = oldlen;
    }
    
    gtk_text_buffer_set_text(GTK_TEXT_BUFFER(self->obj), text, len);
    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_text_buffer_get_selection_bounds noargs
static PyObject *
_wrap_gtk_text_buffer_get_selection_bounds(PyGObject *self, PyObject *args)
{
    GtkTextIter start, end;

    if (!gtk_text_buffer_get_selection_bounds(GTK_TEXT_BUFFER(self->obj),
                                              &start, &end)) {
        return Py_BuildValue ("()");
    }

    return Py_BuildValue("(NN)",
                         pyg_boxed_new(GTK_TYPE_TEXT_ITER, &start, TRUE, TRUE),
                         pyg_boxed_new(GTK_TYPE_TEXT_ITER, &end, TRUE, TRUE));
}
%%
override gtk_text_buffer_insert kwargs
static PyObject *
_wrap_gtk_text_buffer_insert(PyGObject *self, PyObject *args,
                             PyObject *kwargs)
{
    static char *kwlist[] = { "iter", "text", "len", NULL };
    PyObject *py_iter;
    char *text;
    Py_ssize_t len;
    int oldlen = -1;
    GtkTextIter *iter = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os#|i:GtkTextBuffer.insert",
                                     kwlist, &py_iter, &text, &len, &oldlen)) {
        return NULL;
    }

    if (oldlen > 0) {
	if (oldlen > len) {
	    PyErr_SetString(PyExc_ValueError, "len greater than text length");
	    return NULL;
	}
	len = oldlen;
    }

    if (pyg_boxed_check(py_iter, GTK_TYPE_TEXT_ITER)) {
        iter = pyg_boxed_get(py_iter, GtkTextIter);
    } else {
        PyErr_SetString(PyExc_TypeError, "iter should be a GtkTextIter");
        return NULL;
    }
    gtk_text_buffer_insert(GTK_TEXT_BUFFER(self->obj), iter, text, len);
    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_text_buffer_insert_at_cursor kwargs
static PyObject *
_wrap_gtk_text_buffer_insert_at_cursor(PyGObject *self, PyObject *args,
                                       PyObject *kwargs)
{
    static char *kwlist[] = { "text", "len", NULL };
    char *text;
    Py_ssize_t len;
    int oldlen = -1;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "s#|i:GtkTextBuffer.insert_at_cursor",
                                     kwlist, &text, &len, &oldlen)) {
        return NULL;
    }

    if (oldlen > 0) {
	if (oldlen > len) {
	    PyErr_SetString(PyExc_ValueError, "len greater than text length");
	    return NULL;
	}
	len = oldlen;
    }
    
    gtk_text_buffer_insert_at_cursor(GTK_TEXT_BUFFER(self->obj), text, len);
    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_text_buffer_insert_interactive kwargs
static PyObject *
_wrap_gtk_text_buffer_insert_interactive(PyGObject *self, PyObject *args,
                                         PyObject *kwargs)
{
    static char *kwlist[] = { "iter", "text", "default_editable", "len", NULL };
    PyObject *py_iter;
    char *text;
    int default_editable, ret, oldlen = -1;
    Py_ssize_t len;
    GtkTextIter *iter = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "Os#i|i:GtkTextBuffer.insert_interactive",
                                     kwlist, &py_iter, &text, &len,
                                     &default_editable, &oldlen)) {
        return NULL;
    }

    if (oldlen > 0) {
	if (oldlen > len) {
	    PyErr_SetString(PyExc_ValueError, "len greater than text length");
	    return NULL;
	}
	if (oldlen > len) {
	    PyErr_SetString(PyExc_ValueError, "len greater than text length");
	    return NULL;
	}
	len = oldlen;
    }

    if (pyg_boxed_check(py_iter, GTK_TYPE_TEXT_ITER)) {
        iter = pyg_boxed_get(py_iter, GtkTextIter);
    } else {
        PyErr_SetString(PyExc_TypeError, "iter should be a GtkTextIter");
        return NULL;
    }
    ret = gtk_text_buffer_insert_interactive(GTK_TEXT_BUFFER(self->obj), iter,
                                             text, len, default_editable);
    return PyBool_FromLong(ret);
}
%%
override gtk_text_buffer_insert_interactive_at_cursor kwargs
static PyObject *
_wrap_gtk_text_buffer_insert_interactive_at_cursor(PyGObject *self, PyObject *args,
                                                   PyObject *kwargs)
{
    static char *kwlist[] = { "text", "default_editable", "len", NULL };
    char *text;
    Py_ssize_t len;
    int default_editable, ret, oldlen = -1;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "s#i|i:GtkTextBuffer.insert_interactive_at_cursor",
                                     kwlist, &text, &len, &default_editable, &oldlen)) {
        return NULL;
    }

    if (oldlen > 0) {
	len = oldlen;
    }

    ret = gtk_text_buffer_insert_interactive_at_cursor(GTK_TEXT_BUFFER(self->obj),
                                                       text, len, default_editable);
    return PyBool_FromLong(ret);
}
%%
override gtk_text_buffer_get_iter_at_child_anchor kwargs
static PyObject *
_wrap_gtk_text_buffer_get_iter_at_child_anchor(PyGObject *self, PyObject *args,
					       PyObject *kwargs)
{
    static char *kwlist[] = { "anchor", NULL };
    PyGObject *anchor;
    GtkTextIter iter;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:GtkTextBuffer.get_iter_at_child_anchor", kwlist, &PyGtkTextChildAnchor_Type, &anchor))
        return NULL;

    gtk_text_buffer_get_iter_at_child_anchor(GTK_TEXT_BUFFER(self->obj),
					     &iter,
					     GTK_TEXT_CHILD_ANCHOR(anchor->obj));
    return pyg_boxed_new(GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE);
}
%%
override gtk_text_tag_table_add kwargs
static PyObject *
_wrap_gtk_text_tag_table_add(PyGObject *self, PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = { "tag", NULL };
    GtkTextTag *tag;
    GtkTextTagTable *table;
    PyGObject *pytag;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:GtkTextTagTable.add",
				     kwlist, &PyGtkTextTag_Type, &pytag)) {
        return NULL;
    }

    tag = GTK_TEXT_TAG(pytag->obj);
    table = GTK_TEXT_TAG_TABLE(self->obj);

    if (tag->table) {
        gchar buf[512];
        g_snprintf(buf, sizeof(buf),
                   "The tag is already in a tag table");

        PyErr_SetString(PyExc_ValueError, buf);
        return NULL;
    }

    if (tag->name && table && g_hash_table_lookup(table->hash, tag->name)) {
        gchar buf[512];
        g_snprintf(buf, sizeof(buf),
                   "A tag named '%s' is already in the tag table",
                   tag->name);

        PyErr_SetString(PyExc_ValueError, buf);
        return NULL;
    }

    gtk_text_tag_table_add(table, tag);

    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_text_tag_table_remove kwargs
static PyObject *
_wrap_gtk_text_tag_table_remove(PyGObject *self, PyObject *args,
				PyObject *kwargs)
{
    static char *kwlist[] = { "tag", NULL };
    GtkTextTag *tag;
    GtkTextTagTable *table;
    PyGObject *pytag;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
				     "O!:GtkTextTagTable.remove",
				     kwlist, &PyGtkTextTag_Type, &pytag)) {
        return NULL;
    }

    tag = GTK_TEXT_TAG(pytag->obj);
    table = GTK_TEXT_TAG_TABLE(self->obj);

    if (tag->table != table) {
        gchar buf[512];
	if (tag->name)
	    g_snprintf(buf, sizeof(buf),
		       "The tag named '%s' is not in the tag table",
		       tag->name);
	else
	    g_snprintf(buf, sizeof(buf),
		       "The tag is not in the tag table");

        PyErr_SetString(PyExc_ValueError, buf);
        return NULL;
    }

    gtk_text_tag_table_remove(table, tag);

    Py_INCREF(Py_None);
    return Py_None;
}
%%
override-attr GtkTextAttributes.bg_color
static PyObject *
_wrap_gtk_text_attributes__get_bg_color(PyObject *self, void *closure)
{
    GdkColor ret;

    ret = pyg_boxed_get(self, GtkTextAttributes)->appearance.bg_color;
    /* pyg_boxed_new handles NULL checking */
    return pyg_boxed_new(GDK_TYPE_COLOR, &ret, TRUE, TRUE);
}
%%
override-attr GtkTextAttributes.fg_color
static PyObject *
_wrap_gtk_text_attributes__get_fg_color(PyObject *self, void *closure)
{
    GdkColor ret;

    ret = pyg_boxed_get(self, GtkTextAttributes)->appearance.fg_color;
    /* pyg_boxed_new handles NULL checking */
    return pyg_boxed_new(GDK_TYPE_COLOR, &ret, TRUE, TRUE);
}
%%
override-attr GtkTextAttributes.bg_stipple
static PyObject *
_wrap_gtk_text_attributes__get_bg_stipple(PyObject *self, void *closure)
{
    GdkBitmap *ret;

    ret = pyg_boxed_get(self, GtkTextAttributes)->appearance.bg_stipple;
    /* pygobject_new handles NULL checking */
    return pygobject_new((GObject *)ret);
}
%%
override-attr GtkTextAttributes.fg_stipple
static PyObject *
_wrap_gtk_text_attributes__get_fg_stipple(PyObject *self, void *closure)
{
    GdkBitmap *ret;

    ret = pyg_boxed_get(self, GtkTextAttributes)->appearance.fg_stipple;
    /* pygobject_new handles NULL checking */
    return pygobject_new((GObject *)ret);
}
%%
override-attr GtkTextAttributes.rise
static PyObject *
_wrap_gtk_text_attributes__get_rise(PyObject *self, void *closure)
{
    int ret;

    ret = pyg_boxed_get(self, GtkTextAttributes)->appearance.rise;
    return PyInt_FromLong(ret);
}
%%
override-attr GtkTextAttributes.underline
static PyObject *
_wrap_gtk_text_attributes__get_underline(PyObject *self, void *closure)
{
    int ret;

    ret = pyg_boxed_get(self, GtkTextAttributes)->appearance.underline;
    return PyInt_FromLong(ret);
}
%%
override-attr GtkTextAttributes.strikethrough
static PyObject *
_wrap_gtk_text_attributes__get_strikethrough(PyObject *self, void *closure)
{
    return PyBool_FromLong(pyg_boxed_get(self, GtkTextAttributes)->appearance.strikethrough);
}
%%
override-attr GtkTextAttributes.draw_bg
static PyObject *
_wrap_gtk_text_attributes__get_draw_bg(PyObject *self, void *closure)
{
    return PyBool_FromLong(pyg_boxed_get(self, GtkTextAttributes)->appearance.draw_bg);
}
%%
override gtk_text_tag_table_foreach kwargs
static void
pygtk_text_tag_table_foreach_cb(GtkTextTag *tag, gpointer user_data)
{
    PyGILState_STATE state;
    PyObject *callback, *args, *ret;

    state = pyg_gil_state_ensure();
    callback = PyTuple_GetItem((PyObject *)user_data, 0);
    args = Py_BuildValue("(NO)",
			 pygobject_new((GObject *)tag),
			 PyTuple_GetItem((PyObject *)user_data, 1));
    ret = PyObject_CallObject(callback, args);
    if (!ret)
	PyErr_Print();
    Py_DECREF(args);
    Py_XDECREF(ret);
    pyg_gil_state_release(state);
}
static PyObject *
_wrap_gtk_text_tag_table_foreach(PyGObject *self, PyObject *args,
				 PyObject *kwargs)
{
    static char *kwlist[] = { "func", "data",  NULL };
    PyObject *func, *data, *py_data = Py_None;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
				     "O|O:GtkTextTagTable.foreach",
				     kwlist, &func, &py_data)) {
        return NULL;
    }
    if (!PyCallable_Check(func)) {
	PyErr_SetString(PyExc_TypeError, "func must be callable");
	return NULL;
    }

    data = Py_BuildValue("(OO)", func, py_data);
    
    gtk_text_tag_table_foreach(GTK_TEXT_TAG_TABLE(self->obj),
			       pygtk_text_tag_table_foreach_cb,
			       (gpointer)data);
    Py_DECREF(data);
    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_text_iter_forward_find_char kwargs
static gboolean
pygtk_find_char_pred(gunichar ch, gpointer user_data)
{
    PyGILState_STATE state;
    PyObject *pred, *args, *pyret = Py_False;
    gboolean ret;

    state = pyg_gil_state_ensure();

#if !defined(Py_UNICODE_SIZE) || Py_UNICODE_SIZE == 2
    if (ch > 0xffff) {
        PyErr_SetString(PyExc_RuntimeError,
			"character can not be represented in 16-bit unicode");
	PyErr_Print();
        return FALSE;
    }
#endif
    pred = PyTuple_GetItem((PyObject *)user_data, 0);
    args = Py_BuildValue("(NO)", PyUnicode_FromUnicode((Py_UNICODE *)&ch, 1),
			 PyTuple_GetItem((PyObject *)user_data, 1));

    pyret = PyObject_CallObject(pred, args);
    if (!pyret)
	PyErr_Print();
    ret = (pyret == Py_True) ? TRUE : FALSE;

    Py_XDECREF(pyret);
    pyg_gil_state_release(state);

    return ret;
}
static PyObject *
_wrap_gtk_text_iter_forward_find_char(PyGObject *self, PyObject *args,
				      PyObject *kwargs)
{
    static char *kwlist[] = { "pred", "user_data", "limit", NULL };
    GtkTextIter *iter, *limit = NULL;
    gboolean ret;
    PyObject *pylimit = Py_None, *pred, *data, *pydata = Py_None;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
				     "O|OO:gtk.TextIter.forward_find_char",
				     kwlist, &pred, &pydata, &pylimit))
	return NULL;

    if (pylimit != Py_None) {
	if (pyg_boxed_check(pylimit, GTK_TYPE_TEXT_ITER)) {
	    limit = pyg_boxed_get(pylimit, GtkTextIter);
	} else {
	    PyErr_SetString(PyExc_TypeError,
			    "limit should be a gtk.TextIter or None");
	    return NULL;
	}
    }
    if (!PyCallable_Check(pred)) {
	PyErr_SetString(PyExc_TypeError, "pred must be callable");
	return NULL;
    }

    data = Py_BuildValue("(OO)", pred, pydata);
    iter = pyg_boxed_get(self, GtkTextIter);

    ret = gtk_text_iter_forward_find_char(iter, pygtk_find_char_pred,
					  (gpointer)data, limit);

    return PyBool_FromLong(ret);
}
%%
override gtk_text_iter_backward_find_char kwargs
static PyObject *
_wrap_gtk_text_iter_backward_find_char(PyGObject *self, PyObject *args,
				       PyObject *kwargs)
{
    static char *kwlist[] = { "pred", "user_data", "limit", NULL };
    GtkTextIter *iter, *limit = NULL;
    gboolean ret;
    PyObject *pylimit = Py_None, *pred, *data, *pydata = Py_None;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
				     "O|OO:gtk.TextIter.backward_find_char",
				     kwlist, &pred, &pydata, &pylimit))
	return NULL;

    if (pylimit != Py_None) {
	if (pyg_boxed_check(pylimit, GTK_TYPE_TEXT_ITER)) {
	    limit = pyg_boxed_get(pylimit, GtkTextIter);
	} else {
	    PyErr_SetString(PyExc_TypeError,
			    "limit should be a gtk.TextIter or None");
	    return NULL;
	}
    }
    if (!PyCallable_Check(pred)) {
	PyErr_SetString(PyExc_TypeError, "pred must be callable");
	return NULL;
    }

    data = Py_BuildValue("(OO)", pred, pydata);
    iter = pyg_boxed_get(self, GtkTextIter);

    ret = gtk_text_iter_backward_find_char(iter, pygtk_find_char_pred,
					   (gpointer)data, limit);

    return PyBool_FromLong(ret);
}
%%
override gtk_text_view_get_default_attributes noargs
/* Workaround gtk bug #317455; moreover, copy_boxed should have been FALSE
 * in the first place (missing caller-owns-return in the defs) */
static PyObject *
_wrap_gtk_text_view_get_default_attributes(PyGObject *self)
{
    GtkTextAttributes *ret;

    ret = gtk_text_view_get_default_attributes(GTK_TEXT_VIEW(self->obj));
    /* pyg_boxed_new handles NULL checking */
    return pyg_boxed_new(GTK_TYPE_TEXT_ATTRIBUTES, ret, FALSE, TRUE);
}
%%
override gtk_text_view_get_iter_at_position kwargs
static PyObject *
_wrap_gtk_text_view_get_iter_at_position(PyGObject *self, PyObject *args,
                                         PyObject *kwargs)
{
    static char *kwlist[] = { "x", "y", NULL };
    GtkTextIter iter;
    gint x, y, trailing;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "ii:GtkTextView.get_iter_at_position",
                                     kwlist, &x, &y))
        return NULL;
    gtk_text_view_get_iter_at_position(GTK_TEXT_VIEW(self->obj),
                                       &iter, &trailing, x, y);
    return Py_BuildValue("Oi",
                          pyg_boxed_new(GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE),
                          trailing);
}
%%
override gtk_text_buffer_get_copy_target_list noargs
static PyObject*
_wrap_gtk_text_buffer_get_copy_target_list(PyGObject *self)
{
    GtkTargetList *targets;
    PyObject *py_targets;

    targets = gtk_text_buffer_get_copy_target_list(GTK_TEXT_BUFFER(self->obj));
    py_targets = pygtk_target_list_to_list(targets);
    gtk_target_list_unref(targets);
    return py_targets;
}
%%
override gtk_text_buffer_get_paste_target_list noargs
static PyObject*
_wrap_gtk_text_buffer_get_paste_target_list(PyGObject *self)
{
    GtkTargetList *targets;
    PyObject *py_targets;

    targets = gtk_text_buffer_get_paste_target_list(GTK_TEXT_BUFFER(self->obj));
    py_targets = pygtk_target_list_to_list(targets);
    gtk_target_list_unref(targets);
    return py_targets;
}
%%
override gtk_text_buffer_deserialize kwargs
static PyObject *
_wrap_gtk_text_buffer_deserialize(PyGObject *self, PyObject *args,
                                  PyObject *kwargs)
{
    static char *kwlist[] = { "content_buffer", "format", "iter", "data",
                              NULL };
    Py_ssize_t length;
    PyObject *py_format = NULL, *py_iter;
    GdkAtom format;
    GError *error = NULL;
    int ret;
    guint8 *data;
    PyGObject *content_buffer;
    GtkTextIter *iter = NULL;
 
    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "O!OOs#:GtkTextBuffer.deserialize",
                                     kwlist, &PyGtkTextBuffer_Type,
                                     &content_buffer, &py_format, &py_iter,
                                     &data, &length))
        return NULL;

    format = pygdk_atom_from_pyobject(py_format);
    if (PyErr_Occurred())
        return NULL;

    if (pyg_boxed_check(py_iter, GTK_TYPE_TEXT_ITER))
        iter = pyg_boxed_get(py_iter, GtkTextIter);
    else {
        PyErr_SetString(PyExc_TypeError, "iter should be a GtkTextIter");
        return NULL;
    }

    ret = gtk_text_buffer_deserialize(GTK_TEXT_BUFFER(self->obj),
                                      GTK_TEXT_BUFFER(content_buffer->obj),
                                      format, iter, data, length, &error);
    if (pyg_error_check(&error))
        return NULL;
    return PyBool_FromLong(ret);
}
%%
override gtk_text_buffer_serialize kwargs
static PyObject *
_wrap_gtk_text_buffer_serialize(PyGObject *self, PyObject *args,
                                  PyObject *kwargs)
{
    static char *kwlist[] = { "content_buffer", "format", "start", "end",
                              NULL };
    PyObject *py_format = NULL, *py_start, *py_end;
    GdkAtom format;
    gsize length;
    guint8 *ret;
    PyGObject *content_buffer;
    GtkTextIter *start = NULL, *end = NULL;
    PyObject *py_retval;
 
    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "O!OOO:GtkTextBuffer.serialize",
                                     kwlist, &PyGtkTextBuffer_Type,
                                     &content_buffer, &py_format, &py_start,
                                     &py_end))
        return NULL;

    format = pygdk_atom_from_pyobject(py_format);
    if (PyErr_Occurred())
        return NULL;

    if (pyg_boxed_check(py_start, GTK_TYPE_TEXT_ITER))
        start = pyg_boxed_get(py_start, GtkTextIter);
    else {
        PyErr_SetString(PyExc_TypeError, "start should be a GtkTextIter");
        return NULL;
    }
    if (pyg_boxed_check(py_end, GTK_TYPE_TEXT_ITER))
        end = pyg_boxed_get(py_end, GtkTextIter);
    else {
        PyErr_SetString(PyExc_TypeError, "end should be a GtkTextIter");
        return NULL;
    }

    ret = gtk_text_buffer_serialize(GTK_TEXT_BUFFER(self->obj),
                                      GTK_TEXT_BUFFER(content_buffer->obj),
                                      format, start, end, &length);
    py_retval = PyString_FromStringAndSize((char *) ret, (Py_ssize_t) length);
    g_free(ret);
    return py_retval;
}
%%
override gtk_text_buffer_register_deserialize_format kwargs
static gint
pygtk_text_buffer_register_deserialize_format_cb(GtkTextBuffer *register_buf,
                                                 GtkTextBuffer *content_buf,
                                                 GtkTextIter *iter,
                                                 const guint8 *data,
                                                 gsize length,
                                                 gboolean create_tags,
                                                 gpointer user_data,
                                                 GError **error)
{
    PyGILState_STATE state;
    PyGtkCustomNotify *cunote = user_data;
    PyObject *py_register_buf, *py_content_buf, *py_iter, *py_data, *retobj;
    gboolean ret = FALSE;

    g_assert(cunote->func);

    state = pyg_gil_state_ensure();

    py_register_buf = pygobject_new((GObject*)register_buf);
    py_content_buf = pygobject_new((GObject*)content_buf);
    py_iter = pyg_boxed_new(GTK_TYPE_TEXT_ITER, iter, TRUE, TRUE);
    py_data = PyString_FromStringAndSize((char *) data, length);
    if (cunote->data) {
        retobj = PyEval_CallFunction(cunote->func, "(NNNNiO)",
                                     py_register_buf, py_content_buf,
                                     py_iter, py_data, create_tags,
                                     cunote->data);
    } else {
        retobj = PyEval_CallFunction(cunote->func, "(NNNNi)", py_register_buf,
                                     py_content_buf, py_iter, py_data,
                                     create_tags);
    }

    if (retobj != NULL) {
        ret = PyInt_AsLong(retobj);
        Py_DECREF(retobj);
    } else {
        PyErr_Print();
    }

    pyg_gil_state_release(state);
    return ret;
}
static PyObject *
_wrap_gtk_text_buffer_register_deserialize_format(PyGObject *self,
                                                  PyObject *args,
                                                  PyObject *kwargs)
{
    static char *kwlist[] = { "mime_type", "function", "user_data", NULL };
    PyObject *pyfunc, *pyarg = NULL, *ret;
    PyGtkCustomNotify *cunote;
    const gchar *mimetype;
    GdkAtom atom;
    gchar *name;
  
    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "sO|O:GtkTextBuffer.register_deserialize_format",
                                     kwlist, &mimetype, &pyfunc, &pyarg))
        return NULL;

    if (!PyCallable_Check(pyfunc)) {
        PyErr_SetString(PyExc_TypeError,
                        "function must be a callable object");
        return NULL;
    }
    cunote = g_new0(PyGtkCustomNotify, 1);
    cunote->func = pyfunc;
    cunote->data = pyarg;
    Py_INCREF(cunote->func);
    Py_XINCREF(cunote->data);
 
    atom = gtk_text_buffer_register_deserialize_format(
        GTK_TEXT_BUFFER(self->obj), mimetype,
        pygtk_text_buffer_register_deserialize_format_cb, cunote,
        pygtk_custom_destroy_notify);

    name = gdk_atom_name(atom);
    ret = PyString_FromString(name);
    g_free(name);
    return ret;
}
%%
override gtk_text_buffer_register_serialize_format kwargs
static guint8*
pygtk_text_buffer_register_serialize_format_cb(GtkTextBuffer *register_buf,
                                               GtkTextBuffer *content_buf,
                                               const GtkTextIter *start,
                                               const GtkTextIter *end,
                                               gsize *length,
                                               gpointer user_data)
{
    PyGILState_STATE state;
    PyGtkCustomNotify *cunote = user_data;
    PyObject *py_register_buf, *py_content_buf, *py_start, *py_end;
    PyObject *retobj;
    guint8 *ret;

    g_assert(cunote->func);

    state = pyg_gil_state_ensure();

    py_register_buf = pygobject_new((GObject*)register_buf);
    py_content_buf = pygobject_new((GObject*)content_buf);
    py_start = pyg_boxed_new(GTK_TYPE_TEXT_ITER, (gpointer)start, TRUE, TRUE);
    py_end = pyg_boxed_new(GTK_TYPE_TEXT_ITER, (gpointer)end, TRUE, TRUE);
    if (cunote->data) {
        retobj = PyEval_CallFunction(cunote->func, "(NNNNO)",
                                     py_register_buf, py_content_buf,
                                     py_start, py_end,
                                     cunote->data);
    } else {
        retobj = PyEval_CallFunction(cunote->func, "(NNNN)", py_register_buf,
                                     py_content_buf, py_start, py_end);
    }

    if (retobj != NULL) {
        PyString_AsStringAndSize(retobj, (gchar**)&ret, (Py_ssize_t*) length);
        ret = g_memdup(ret, *length);
        Py_DECREF(retobj);
    } else {
        PyErr_Print();
        ret = NULL;
    }

    pyg_gil_state_release(state);
    return ret;
}
static PyObject *
_wrap_gtk_text_buffer_register_serialize_format(PyGObject *self,
                                                PyObject *args,
                                                PyObject *kwargs)
{
    static char *kwlist[] = { "mime_type", "function", "user_data",
                              NULL };
    PyObject *pyfunc, *pyarg = NULL, *ret;
    PyGtkCustomNotify *cunote;
    const gchar *mimetype;
    GdkAtom atom;
    gchar *name;
  
    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "sO|O:GtkTextBuffer.register_serialize_format",
                                     kwlist, &mimetype, &pyfunc, &pyarg))
        return NULL;

    if (!PyCallable_Check(pyfunc)) {
        PyErr_SetString(PyExc_TypeError,
                        "function must be a callable object");
        return NULL;
    }
    cunote = g_new0(PyGtkCustomNotify, 1);
    cunote->func = pyfunc;
    cunote->data = pyarg;
    Py_INCREF(cunote->func);
    Py_XINCREF(cunote->data);
 
    atom = gtk_text_buffer_register_serialize_format(
        GTK_TEXT_BUFFER(self->obj), mimetype,
        pygtk_text_buffer_register_serialize_format_cb,
        cunote, pygtk_custom_destroy_notify);

    name = gdk_atom_name(atom);
    ret = PyString_FromString(name);
    g_free(name);
    return ret;
}
%%
override gtk_text_buffer_get_deserialize_formats noargs
static PyObject *
_wrap_gtk_text_buffer_get_deserialize_formats(PyGObject *self)
{
    GdkAtom *formats;
    gint n_formats, i;
    PyObject *py_formats;

    formats = gtk_text_buffer_get_deserialize_formats(
        GTK_TEXT_BUFFER(self->obj), &n_formats);

    py_formats = PyList_New(n_formats);
    for (i = 0; i < n_formats; i++) {
        gchar *name = gdk_atom_name(formats[i]);
        PyList_SetItem(py_formats, i, PyString_FromString(name));
        g_free(name);
    }
    g_free(formats);
    return py_formats;
}
%%
override gtk_text_buffer_get_serialize_formats noargs
static PyObject *
_wrap_gtk_text_buffer_get_serialize_formats(PyGObject *self)
{
    GdkAtom *formats;
    gint n_formats, i;
    PyObject *py_formats;

    formats = gtk_text_buffer_get_serialize_formats(
        GTK_TEXT_BUFFER(self->obj), &n_formats);

    py_formats = PyList_New(n_formats);
    for (i = 0; i < n_formats; i++) {
        gchar *name = gdk_atom_name(formats[i]);
        PyList_SetItem(py_formats, i, PyString_FromString(name));
        g_free(name);
    }
    g_free(formats);
    return py_formats;
}
